﻿using System;
using Server.Mobiles;
using Server.Commands;
using Server.Engines.GroupSystem;

namespace Server.Engines.ExpSystem
{
    class ExpSystem
    {
        const int LivelloMaxPlayer = 36;

        public static void Initialize()
        {
            CommandSystem.Register("pxCap", AccessLevel.Player, new CommandEventHandler(PxCap_OnCommand));
        }

        private static void PxCap_OnCommand(CommandEventArgs e)
        {
            if (e.Mobile is PlayerMobile)
            {
                PlayerMobile player = (PlayerMobile)e.Mobile;

                e.Mobile.SendMessage("Livello {0}", player.Livello);
                e.Mobile.SendMessage("Punti Esperienza {0}", player.PuntiEsperienza);
                // TODO: altri messaggi
            }
        }

        public static void killHandler(Mobile killer, Mobile killed)
        {
            // NPG uccide NPG (se il killer appartiene a un PG, e' come se quel PG avesse ucciso l'NPG)
            if (killer is BaseCreature && killed is BaseCreature)
            {
                BaseCreature killerCreature = (BaseCreature)killer;

                if (killerCreature.ControlMaster != null)
                {
                    killer = killerCreature.ControlMaster;
                }
                else
                {
                    // Nulla da fare, un NPG non tamato ha ucciso un altro NPG.
                    return;
                }
            }

            // PG uccide un NPG (guadagnare PX)
            if (killer is PlayerMobile && killed is BaseCreature)
            {
                PlayerMobile killerPlayer = (PlayerMobile)killer;
                BaseCreature killedCreature = (BaseCreature)(killed);  

                // PG non in gruppo di caccia o in gruppo da solo.
                if (killerPlayer.Gruppo == null
                    || !(killerPlayer.Gruppo is GruppoDiCaccia)
                    || killerPlayer.Gruppo.numPartecipanti == 1)
                {
                    // Il PG e' di un livello troppo alto, nn prendi PX
                    if (killerPlayer.Livello > killedCreature.Livello + 6)
                    {
                        killerPlayer.SendMessage("Sei di livello troppo alto, non ricevi PX!");
                        return;
                    }

                    // Il PG e' di un livello troppo basso, nn prendi PX
                    if (killerPlayer.Livello + 3 < killedCreature.Livello)
                    {
                        killerPlayer.SendMessage("Il mostro e' di livello troppo alto, non ricevi PX!");
                        return;
                    }

                    int PxGuadagnati = killedCreature.Esperienza;

                    if (killerPlayer.Livello > killedCreature.Livello)
                    {
                        // Per ogni livello in piu, sono 8.3% PX in meno.
                        int LivelliDiDifferenza = killerPlayer.Livello - killedCreature.Livello;
                        PxGuadagnati -= (int)Math.Round(PxGuadagnati * LivelliDiDifferenza*0.083); 
                    }

                    if (PxGuadagnati < 0)
                        PxGuadagnati = 0;
                 
                    killerPlayer.SendMessage("Guadagni {0} PX.", PxGuadagnati);
                    killerPlayer.PuntiEsperienza += PxGuadagnati;
                }
                else  // Il PG fa parte di un gruppo di 2 o piu componenti.
                {
                    // Il gruppo e' di un livello troppo basso, nn prendi PX
                    if (killerPlayer.Gruppo.MaxLivello + 2 + (killerPlayer.Gruppo.SommaLivelli / 8) < killedCreature.Livello)
                    {
                        foreach (PlayerMobile p in killerPlayer.Gruppo.Partecipanti)
                            p.SendMessage("Il mostro e' di livello troppo alto, non ricevi PX!");

                        return;
                    }
                    
                    int PxGuadagnati = killedCreature.Esperienza;

                    // I PX vengono aumentati in base al numero di componenti del gruppo.
                    switch (killerPlayer.Gruppo.numPartecipanti)
                    {
                        case 2: // + 60%
                            PxGuadagnati += (int)(PxGuadagnati * 0.6);
                            break;
                        case 3: // + 120%
                            PxGuadagnati += (int)(PxGuadagnati * 1.2);
                            break;
                        case 4: // + 180%
                            PxGuadagnati += (int)(PxGuadagnati * 1.8);
                            break;
                        case 5: // + 240%
                            PxGuadagnati += (int)(PxGuadagnati * 2.4);
                            break;
                        case 6:
                        case 7:
                        case 8:  // + 280%                               
                            PxGuadagnati += (int)(PxGuadagnati * 2.8);
                            break;
                        default:
                            killerPlayer.SendMessage("DEBUG: Contattare lo staff, errore #1101");
                            break;
                     }
                   

                     if (killerPlayer.Gruppo.Livello > killedCreature.Livello)
                     {
                        // Per ogni livello in piu, sono 11.1% PX in meno.
                        int LivelliDiDifferenza = killerPlayer.Gruppo.Livello - killedCreature.Livello;
                        PxGuadagnati -= (int)Math.Round(PxGuadagnati * LivelliDiDifferenza * 0.111);
                     }

                     if (PxGuadagnati < 0)
                         PxGuadagnati = 0;

                     // Distribuzione PX ai componenti del gruppo
                     int PxPerComponente = PxGuadagnati / killerPlayer.Gruppo.numPartecipanti;

                     foreach (PlayerMobile p in killerPlayer.Gruppo.Partecipanti)
                     {
                         p.SendMessage("Guadagni {0} PX", PxPerComponente);
                         p.PuntiEsperienza += PxPerComponente;
                     }
                }
            }
            else if (killer is BaseCreature && killed is PlayerMobile)
            {
                PlayerMobile killedPlayer = (PlayerMobile)killed;
                // NPG uccide PG (perdere PX)
                if (killedPlayer.Livello <= LivelloMaxPlayer)
                    killedPlayer.PuntiEsperienza -= m_TabellaExpPersa[killedPlayer.Livello];
            }
            else if (killer is PlayerMobile && killed is PlayerMobile)
            {
                // TODO: PG uccide PG. Bisogna gestire il prestigio qui.
            }
        }

        // Int e' 32 bit (2 miliardi e qualcosa) quindi basta e avanza
        private static int[] m_TabellaExp = new int[]
        {
            0,      // Segnaposto livello 0
            0,      // Segnaposto livello 1
            2000,
            6750,
            15000,
            27800,
            45900,
            70700,
            103500,
            146100,
            200400,  // Livello 10
            268800,
            354100,
            459800,
            588700,
            746000,
            936200,
            1164800,
            1437900,
            1762400,
            2145200,  // Livello 20
            2596800,
            3124600,
            3739200,
            4452000,
            5275000,
            6221400,
            7305400,
            8542400,
            9948900,
            11542700,  // Livello 30
            15606680,
            18147300,
            21101500,
            24536650,
            28531000,
            33175555  // Livello 36 
        };

        private static int[] m_TabellaExpPersa = new int[]
        {
            0,      // Segnaposto livello 0
            0,
            30,     
            101,
            226,
            416,
            688,
            1060,
            1552,
            2191,
            3006,   // Livello 10
            2688,  
            3541,
            4595,
            5887,
            7460,
            9362,
            11648,
            14379,
            17624,
            21459,  // Livello 20
            12948,
            15623,
            18696,
            22260,
            26375,
            31107,
            36525,
            42710,
            49744,
            57714,  // Livello 30
            46820,
            54441,
            63304,
            73609,
            85593,
            99526
        };
    }
}